(function(window) {
    
    var $ = window.jQuery,
        _noop = function() {},
        
        win = window,
        doc = win.document,
        loc = win.location,
        
        htmlHead = doc.getElementsByTagName("head")[0],
        HARDGOODS = 'hardgoods', SOFTGOODS = 'softgoods',
        URIRoot = 'http://192.168.0.176/';
        
    if(window.ShoppingAssistant) return;
    var assistantTPL = {
        'basebar': '<div style="top:auto;" id="kaixin_client_bar">\
                        <div class="kxc_min" style="width:1px">\
                            <div class="kxc_min_inner">\
                                <span>开心购物</span>\
                            </div>\
                        </div>\
                        {{=it.displaybar}}\
                    </div>',
                
        'searchbar': '<div class="kxc_max kxc_max_no_data" style="display:none">\
                        <div class="kxc_max_inner">\
                            <a title="开心购物" href="http://www.kaixin001.com" class="kxc_logo">开心购物</a>\
                            <div class="kxc_search">\
                                <form method="get" target="_blank" action="http://www.kaixin001.com">\
                                    <input type="text" name="key" class="kxc_search_txt">\
                                    <input type="submit" class="kxc_search_btn" value="">\
                                </form>\
                            </div>\
                            <div class="kxc_prompt">{{=it.extinfo}}</div>\
                            <span title="最小化" class="cg_min_btn">最小化</span>\
                        </div>\
                    </div>',
        
        'hardbar': '<div class="kxc_max kxc_max_data_info" style="display:none">\
                        <div class="kxc_max_inner">\
                            <a title="开心购物" href="http://www.kaixin001.com" class="kxc_logo">开心购物</a>\
                            <div class="kxc_goods_name"><a href="">{{=it.goodsname}}</a></div>\
                            <div class="kxc_shop_item">\
                                {{=it.goodsItems}}\
                            </div>\
                            <span title="最小化" class="cg_min_btn">最小化</span>\
                        </div>\
                    </div>',
                    
        'softbar': '<div class="kxc_max kxc_max_data_info" style="display:none">\
                        <div class="kxc_max_inner">\
                            <a title="开心购物" href="http://www.kaixin001.com" class="kxc_logo">开心购物</a>\
                            <div class="kxc_shop_item kxc_smlr_item">\
                                <div class="kxc_smlr_lab">相似商品：</div>\
                                {{=it.goodsItems}}\
                            </div>\
                            <span title="最小化" class="cg_min_btn">最小化</span>\
                        </div>\
                    </div>',
                    
        'hardItems': '<div class="kxc_item">\
                        <a target="_blank" href="" class="kxc_item_link">{{=it.com}}：{{=it.price}}</a>\
                        <div class="kxc_item_info">\
                            <div class="kxc_item_info_hd"><a href="{{=it.titlelink}}">{{=it.title}}</a></div>\
                            <div class="kxc_item_info_bd">\
                                <div class="bd_inner">\
                                    <ul>\
                                        {{=it.items}}\
                                    </ul>\
                                </div>\
                            </div>\
                        </div>\
                    </div>',
                    
        'softItem': '<div class="kxc_item">\
                        <a target="_blank" href="" class="kxc_item_link">{{=it.shortname}}</a>\
                        <div class="kxc_item_info">\
                            <div class="kxc_smlr_inner">\
                                <span class="kxc_goods_pic"><a href=""><img src="{{=it.img}}"></a></span>\
                                <p class="kxc_goods_info">价格：{{=it.price}}<br>{{=it.name}}</p>\
                            </div>\
                        </div>\
                    </div>',
                    
        'hardItem': '<li>{{=it.iteminfo}}</li>'
    }
    
    var ShoppingAssistant = function() {

        this.init();
        
    };
    window.ShoppingAssistant = ShoppingAssistant;
    
    ShoppingAssistant.prototype = {
        
        'version': 1.0,
        
        'extinfo': '今天天气不错，购物好心情',
        
        'JSURI': 'scDemo/process.php',

        'shopInfo': null,
        
        'assistantBar': null,
        
        'init' : function() {
            this.getShopInfo();
            this.loadShoppingAssistant();
        },
        
        'getShopInfo' : function() {
            var domain = loc.hostname;
            this.getDomainShopInfo(domain);
        },
        
        'getDomainShopInfo' : function(domain) {
            var infoParser = ShoppingAssistant.domainParser[domain];
            if(infoParser) {
                this.shopInfo = infoParser();
            }
        },
        
        'loadShoppingAssistant' : function() {
            var assistantScriptURI, jsonp = this.getJSONP();
            if(this.shopInfo) {
                assistantScriptURI = URIRoot + this.JSURI + '?' + Utils.URIParams(this.shopInfo);
                assistantScriptURI += '&jsonp='+jsonp;
                win[jsonp] = Utils.proxy(this.showAssistant, this);
                Resource.loadSingleJS(assistantScriptURI);
            }
        },
        
        'showAssistant' : function(data) {
            var assistantHTML = null, _this = this;
            if(data && data.list && data.list.length) {
                if(data.type === HARDGOODS) {
                    assistantHTML = this.getHardGoodsHTML(data);
                } else if(data.type === SOFTGOODS) {
                    assistantHTML = this.getSoftGoodsHTML(data);
                }
            } else {
                assistantHTML = this.getSearchBarHTML(data && data.extinfo || this.extinfo);
            }
            if(assistantHTML && data.versionCSS) {
                Resource.loadSingleCSS(data.versionCSS, function() {
                    _this.getInfo = data.get;
                    _this.assistantBar = $(assistantHTML).appendTo('body');
                    _this.bindEvents();
                    _this.showAssistantBar();
                });
            }
        },
        
        'showAssistantBar' : function() {
            var minBar = this.assistantBar.children('.kxc_min');
            this.assistantBar.show();
            minBar.animate({'width':118}, 400);
        },
        
        'getHardGoodsHTML' : function(goods) {
            var goodsList = goods.list, goodsItems = [], item,
                innerGoodsList, innerGoodsItems, innerItem;
            while(item = goodsList.shift()) {
                innerGoodsList = item.list;
                innerGoodsItems = []
                while(innerItem = innerGoodsList.shift()) {
                    innerGoodsItems.push(doT.template(assistantTPL.hardItem)(innerItem));
                }
                goodsItems.push(doT.template(assistantTPL.hardItems)({
                    'com':item.com,
                    'title':item.title,
                    'price':item.price,
                    'link':item.link,
                    'items':innerGoodsItems.join('')
                }));
            }
            
            return doT.template(assistantTPL.basebar)({
                'displaybar': doT.template(assistantTPL.hardbar)({
                    'goodsname': goods.name,
                    'goodsItems': goodsItems.join('')
                })
            });
        },
        
        'getSoftGoodsHTML' : function(goods) {
            var goodsList = goods.list,
                goodsItems = [], item;
            while(item = goodsList.shift()) {
                goodsItems.push(doT.template(assistantTPL.softItem)(item));
            }
            
            return doT.template(assistantTPL.basebar)({
                'displaybar': doT.template(assistantTPL.softbar)({
                    'goodsname': goods.name,
                    'goodsItems': goodsItems.join('')
                })
            });
        },
        
        'getSearchBarHTML' : function(info) {
            return doT.template(assistantTPL.basebar)({
                'displaybar': doT.template(assistantTPL.searchbar)({
                    'extinfo':info
                })
            });
        },
        
        'bindEvents' : function() {
            try { console.info(this.assistantBar); } catch(e) {}
            if(this.assistantBar) {
                this.assistantBar.children('.kxc_min').bind('click', Utils.proxy(this.expandBar, this));
                this.assistantBar.find('.cg_min_btn').bind('click', Utils.proxy(this.retainBar, this));
                try { console.info(this.assistantBar.find('.kxc_item')); } catch(e) {};
                this.assistantBar.find('.kxc_item').bind('mouseenter', function(ev) {
                    $(this).addClass('kxc_item_hov');
                }).bind('mouseleave', function(ev) {
                    $(this).removeClass('kxc_item_hov');
                });
            }
        },
        
        'getJSONP' : function() {
            var t = + new Date();
            while (win['show_shopping_assistant_'+t]) { t++; }
            return 'show_shopping_assistant_'+t;
        },
        
        'expandBar' : function(ev) {
            var $target = $(ev.currentTarget),
                maxBar = this.assistantBar.children('.kxc_max'),
                docWidth = Geometry.docWidth();
            maxBar.css('right', -docWidth);
            $target.animate({'width': 1}, 400, function() {
                $target.hide();
                maxBar.show();
                maxBar.animate({'right': 0}, 1000);
            });
            ev.preventDefault();
        },
        
        'retainBar' : function(ev) {
            var minBar = this.assistantBar.children('.kxc_min'),
                maxBar = this.assistantBar.children('.kxc_max'),
                docWidth = Geometry.docWidth();
            alert(this.getInfo);
            maxBar.animate({'right': -docWidth}, 1000, function() {
                maxBar.hide();
                minBar.show();
                minBar.animate({'width': 118}, 400);
            });
            ev.preventDefault();
        }
    };
    
    /**
     * 针对不同的domain获取不同的shop info
     */
    ShoppingAssistant.domainParser = {
        'www.okbuy.com': function() {
            var pathname = loc.pathname,
                detailPageReg = /^\/com\/[0-9]+\.html$/,
                shopInfo = {
                    'domain': 'okbuy',
                    'category': 'shoe',
                    'link': loc.href
                };
            if(detailPageReg.test(pathname)) {
                try {
                    var propertyTitle = $('.c_top_r .title').find('h1').text().split(/\s/),
                        propertyDOM = $('.comdtl').find('td');
                    shopInfo.price = parseInt($('.market_pr').text(), 10);
                    shopInfo.brand = propertyTitle[0];
                    shopInfo.gender = propertyTitle[1];
                    shopInfo.style = propertyTitle[2];
                    shopInfo.material = $(propertyDOM[0]).html().toLowerCase().split('<br>')[1].split('：')[1];
                    shopInfo.color = $(propertyDOM[2]).html().toLowerCase().split('<br>')[0].split('：')[1];
                    shopInfo.artNo = $(propertyDOM[0]).html().toLowerCase().split('<br>')[0].split('：')[1];
                    shopInfo.image = $('img[name=targetimage]').attr('src').replace(/_\d\.jpg/, '_4.jpg');
                } catch(e) {
                    // TODO:log error here!
                }
            }
            
            return shopInfo;
        },
        
        'www.letao.com': function() {
            var pathname = loc.pathname,
                detailPageReg = /^\/shoe-[^\/\.\~\:]+$/,
                shopInfo = {
                    'domain': 'letao',
                    'category': 'shoe',
                    'link': loc.href
                };
            if(detailPageReg.test(pathname)) {
                try {
                    var propertys = $('#shoe_property').find('td');
                    shopInfo.price = parseInt($('.ltprice.big').text(), 10);
                    shopInfo.brand = $('#ltlinknav').children('a[lt_stat_id=prod_guid_category3]').text();
                    shopInfo.gender = $(propertys[4]).text();
                    shopInfo.style = $(propertys[1]).text();
                    shopInfo.material = $(propertys[2]).text();
                    shopInfo.color = $(propertys[5]).text();
                    shopInfo.artNo = $(propertys[3]).text();
                    shopInfo.image = $($('#imgpoint li')[3]).children('img').attr('src').replace(/_\d+\.jpg/, '_11.jpg');
                } catch(e) {
                    // TODO:log error here!
                }
            }
            return shopInfo;
        },
        
        'www.360buy.com': function() {
            var pathname = loc.pathname,
                detailPageReg = /^\/shoe-[^\/\.\~\:]+$/,
                shopInfo = {
                    'domain': '360buy',
                    'category': 'shoe',
                    'link': loc.href
                };
            
            return shopInfo;
        }
    };
    
    /**
     * load js and css
     */
    var Resource = {
        'loadSingleJS': function(url, callback) {
            var script = doc.createElement("script"),
                callback = typeof callback === 'function' ? callback : _noop;
                
            script.setAttribute("type", "text/javascript");
            if (script.readyState){ //IE
                script.onreadystatechange = function(){
                    if (script.readyState == "loaded" || script.readyState == "complete"){
                        script.onreadystatechange = null;
                        callback();
                    }
                };
            } else {
                script.onload = function(){
                    callback();
                };
            }
            script.setAttribute("src", url);
            htmlHead.appendChild(script);
        },
        
        'loadSingleCSS': function(url, callback) {
            var link = doc.createElement("link"),
                callback = typeof callback === 'function' ? callback : _noop;
                
            link.setAttribute("rel", "Stylesheet");
            link.setAttribute("type", "text/css");
            link.setAttribute("href", url);
            htmlHead.appendChild(link);
            callback();
        }
    }

    /**
     * 工具类
     */
    var Utils = {
        'getDomain': function() {
            return loc.hostname;
        },
        
        'URIParams': function(obj) {
            var params = [];
            if(typeof obj === 'object') {
                for(var key in obj) {
                    if(obj.hasOwnProperty(key)) {
                        params.push(key+'='+encodeURIComponent(obj[key]));
                    }
                }
            }
            return params.join('&');
        },
        
        'proxy': function(func, context) {
            func = typeof func === 'function' ? func : _noop;
            context = typeof context === 'undefined' ? win : context;
            return function(data) {
                func.apply(context, [].concat(data));
            }
        }
        
    };
    
    /**
     * doT js
     */
    var doT = { version : '0.1.3' };
    doT.templateSettings = {
        evaluate : /\{\{([\s\S]+?)\}\}/g,
        interpolate : /\{\{=([\s\S]+?)\}\}/g,
        encode :  /\{\{!([\s\S]+?)\}\}/g,
        defines:  /\{\{#([\s\S]+?)\}\}/g,
        varname : 'it',
        strip : true
    };
    doT.template = function(tmpl, c, defs) {
        c = c || doT.templateSettings;
        var str = ("var out='" +
                ((c.strip) ? tmpl.replace(/\s*<!\[CDATA\[\s*|\s*\]\]>\s*|[\r\n\t]|(\/\*[\s\S]*?\*\/)/g, ''):
                             tmpl)
                .replace(c.defines, function(match, code) {
                    return eval(code.replace(/[\r\t\n]/g, ' '));
                })
                .replace(/\\/g, '\\\\')
                .replace(/'/g, "\\'")
                .replace(c.interpolate, function(match, code) {
                    return "';out+=" + code.replace(/\\'/g, "'").replace(/\\\\/g,"\\").replace(/[\r\t\n]/g, ' ') + ";out+='";
                })
                .replace(c.encode, function(match, code) {
                    return "';out+=(" + code.replace(/\\'/g, "'").replace(/\\\\/g, "\\").replace(/[\r\t\n]/g, ' ') + ").toString().replace(/&(?!\\w+;)/g, '&#38;').split('<').join('&#60;').split('>').join('&#62;').split('" + '"' + "').join('&#34;').split(" + '"' + "'" + '"' + ").join('&#39;').split('/').join('&#x2F;');out+='";
                })
                .replace(c.evaluate, function(match, code) {
                    return "';" + code.replace(/\\'/g, "'").replace(/\\\\/g,"\\").replace(/[\r\t\n]/g, ' ') + "out+='";
                })
                + "';return out;")
                .replace(/\n/g, '\\n')
                .replace(/\t/g, '\\t')
                .replace(/\r/g, '\\r')
                .split("out+='';").join('')
                .split('var out="";out+=').join('var out=');
        try {
            return new Function(c.varname, str);
        } catch (e) {
            if (typeof console !== 'undefined') console.log("Could not create a template function: " + str);
            throw e;
        }
    };
    
    /**
     * Geometry js
     */
    var Geometry = { // 默认返回0,避免在一些隐藏iframe中无法获取数据报错
            'winX' : function() { return 0; },
            'winY' : function() { return 0; },
            'viewportWidth' : function() { return 0; },
            'viewportHeight' : function() { return 0; },
            'scrollLeft' : function() { return 0; },
            'scrollTop' : function() { return 0; },
            'docWidth' : function() { return 0; },
            'docHeight' : function() { return 0; }
        };
    if (win.screenLeft) { // IE and others
        Geometry.winX = function() { return win.screenLeft; };
        Geometry.winY = function() { return win.screenTop; };
    } else if (win.screenX) { // Firefox and others
        Geometry.winX = function() { return win.screenX; };
        Geometry.winY = function() { return win.screenY; };
    }
    if (win.innerWidth) { // All browsers but IE
        Geometry.viewportWidth = function() { return win.innerWidth; };
        Geometry.viewportHeight = function() { return win.innerHeight; };
        Geometry.scrollLeft = function() { return win.pageXOffset; };
        Geometry.scrollTop = function() { return win.pageYOffset; };
    } else if (doc.documentElement && doc.documentElement.clientWidth) {
        // These functions are for IE 6 when there is a DOCTYPE
        Geometry.viewportWidth = function() { return doc.documentElement.clientWidth; };
        Geometry.viewportHeight = function() { return doc.documentElement.clientHeight; };
        Geometry.scrollLeft = function() { return doc.documentElement.scrollLeft; };
        Geometry.scrollTop = function() { return doc.documentElement.scrollTop; };
    } else if (doc.body.clientWidth) {
        // These are for IE4, IE5, and IE6 without a DOCTYPE
        Geometry.viewportWidth = function() { return doc.body.clientWidth; };
        Geometry.viewportHeight = function() { return doc.body.clientHeight; };
        Geometry.scrollLeft = function() { return doc.body.scrollLeft; };
        Geometry.scrollTop = function() { return doc.body.scrollTop; };
    } 
    // These functions return the size of the document. They are not window
    // related, but they are useful to have here anyway.
    if (doc.documentElement && doc.documentElement.scrollWidth) {
        Geometry.docWidth = function() { return doc.documentElement.scrollWidth; };
        Geometry.docHeight = function() { return doc.documentElement.scrollHeight; };
    } else if (document.body.scrollWidth) {
        Geometry.docWidth = function() { return doc.body.scrollWidth; };
        Geometry.docHeight = function() { return doc.body.scrollHeight; };
    }
    
    // 实例化shopping assistant，运行之
    new ShoppingAssistant();
    
})(window);